import moment from 'moment'
import { getDayConfigs, validateSignTime, validateSignTimeByParams } from '@/api/campus/trainSignTimeConfig'

/**
 * 签到时间验证工具类
 * 提供统一的签到时间验证逻辑和配置管理
 */
class SignTimeValidator {
  constructor() {
    this.configCache = new Map() // 缓存时间配置
    this.cacheExpiry = 5 * 60 * 1000 // 缓存5分钟
  }

  /**
   * 获取签到时间配置（带缓存）
   * @param {string} trainId 师训ID
   * @param {string} signDate 签到日期
   * @param {string} period 时段
   * @returns {Promise<Object>} 时间配置
   */
  async getTimeConfig(trainId, signDate, period) {
    const cacheKey = `${trainId}_${signDate}_${period}`
    const cached = this.configCache.get(cacheKey)

    if (cached && Date.now() - cached.timestamp < this.cacheExpiry) {
      return cached.data
    }

    try {
      const res = await getDayConfigs(trainId, signDate)
      const configs = res.data || []
      const config = configs.find(item => item.periodName === period)

      // 缓存配置
      this.configCache.set(cacheKey, {
        data: config,
        timestamp: Date.now()
      })

      return config
    } catch (error) {
      console.error('获取时间配置失败:', error)
      return null
    }
  }

  /**
   * 验证签到时间的基础规则
   * @param {string} signTime 签到时间
   * @param {string} signDate 签到日期
   * @param {string} period 时段
   * @returns {Object} 验证结果
   */
  validateBasicRules(signTime, signDate, period) {
    if (!signTime) {
      return { valid: false, message: '请选择签到时间' }
    }

    const signMoment = moment(signTime)
    const dateMoment = moment(signDate)
    const now = moment()

    // 验证签到时间不能超过当前时间
    if (signMoment.isAfter(now)) {
      return { valid: false, message: '签到时间不能超过当前时间' }
    }

    // 验证签到时间必须在签到日期当天
    if (!signMoment.isSame(dateMoment, 'day')) {
      return { valid: false, message: '签到时间必须在签到日期当天' }
    }

    // 验证时段与时间的匹配性
    const hour = signMoment.hour()
    const periodRules = this.getPeriodTimeRules()
    const rule = periodRules[period]

    if (rule && (hour < rule.start || hour >= rule.end)) {
      return {
        valid: false,
        message: `${rule.label}时段的签到时间应在${rule.start}:00-${rule.end - 1}:59之间`
      }
    }

    return { valid: true }
  }

  /**
   * 获取时段时间规则
   * @returns {Object} 时段规则配置
   */
  getPeriodTimeRules() {
    return {
      AM: { start: 6, end: 12, label: '上午' },
      PM: { start: 12, end: 18, label: '下午' },
      EVE: { start: 18, end: 24, label: '晚上' }
    }
  }

  /**
   * 验证签到时间（简化版本）
   * @param {Object} params 验证参数
   * @returns {Promise<Object>} 验证结果
   */
  async validateSignTime(params) {
    const { trainId, signTime, signDate, period, teacherId } = params

    // 基础验证
    const basicResult = this.validateBasicRules(signTime, signDate, period)
    if (!basicResult.valid) {
      return basicResult
    }

    try {
      // 获取时间配置
      const config = await this.getTimeConfig(trainId, signDate, period)
      if (!config || !config.isEnabled) {
        return { valid: false, message: '签到时间配置不可用' }
      }

      // 时间计算
      const signMoment = moment(signTime)
      const configDateStr = moment(signDate).format('YYYY-MM-DD')
      const startTime = moment(`${configDateStr} ${config.startTime}`)
      const endTime = moment(`${configDateStr} ${config.endTime}`)
      const lateDeadline = endTime.clone().add(config.lateMinutes || 15, 'minutes')

      // 时间范围检查
      if (signMoment.isBefore(startTime)) {
        return { valid: false, message: `签到时间不能早于${config.startTime}` }
      }

      if (signMoment.isAfter(lateDeadline)) {
        return { valid: false, message: '签到时间超出允许范围' }
      }

      // 确定签到状态
      let status = 'Normal' // 正常
      let message = '签到成功'

      if (signMoment.isAfter(endTime)) {
        status = 'Late' // 迟到
        const lateMinutes = signMoment.diff(endTime, 'minutes')
        message = `签到成功（迟到${lateMinutes}分钟）`
      }

      return {
        valid: true,
        message,
        status,
        isLate: status === 'Late',
        lateMinutes: status === 'Late' ? signMoment.diff(endTime, 'minutes') : 0,
        config
      }
    } catch (error) {
      console.error('签到时间验证失败:', error)
      return { valid: false, message: '签到时间验证失败，请稍后重试' }
    }
  }

  /**
   * 获取智能默认签到时间
   * @param {string} period 时段
   * @param {string} signDate 签到日期
   * @returns {string} 默认签到时间
   */
  getSmartDefaultTime(period, signDate) {
    const date = moment(signDate || moment().format('YYYY-MM-DD'))
    const now = moment()

    // 如果是今天，使用当前时间
    if (date.isSame(now, 'day')) {
      return now.format('YYYY-MM-DD HH:mm:ss')
    }

    // 根据时段设置默认时间
    const defaultTimes = {
      AM: { hour: 9, minute: 0 },
      PM: { hour: 14, minute: 0 },
      EVE: { hour: 19, minute: 0 }
    }

    const defaultTime = defaultTimes[period] || defaultTimes['AM']
    return date
      .hour(defaultTime.hour)
      .minute(defaultTime.minute)
      .second(0)
      .format('YYYY-MM-DD HH:mm:ss')
  }

  /**
   * 获取智能默认时段
   * @returns {string} 默认时段
   */
  getSmartDefaultPeriod() {
    const hour = moment().hour()
    if (hour < 12) {
      return 'AM'
    } else if (hour < 18) {
      return 'PM'
    } else {
      return 'EVE'
    }
  }

  /**
   * 清除配置缓存
   */
  clearCache() {
    this.configCache.clear()
  }

  /**
   * 获取时段标签
   * @param {string} period 时段
   * @returns {string} 时段标签
   */
  getPeriodLabel(period) {
    const labelMap = {
      AM: '上午',
      PM: '下午',
      EVE: '晚上'
    }
    return labelMap[period] || period
  }

  /**
   * 获取状态标签
   * @param {string} status 状态
   * @returns {string} 状态标签
   */
  getStatusLabel(status) {
    const labelMap = {
      Normal: '正常',
      Late: '迟到',
      Leave: '请假',
      EarlyLeave: '早退',
      Absent: '缺勤'
    }
    return labelMap[status] || status
  }
}

// 创建单例实例
const signTimeValidator = new SignTimeValidator()

export default signTimeValidator

// 导出常用方法
export const { validateSignTime: validateTime, validateBasicRules, getSmartDefaultTime, getSmartDefaultPeriod, getPeriodLabel, getStatusLabel, clearCache } = signTimeValidator
